package com.xiongwei.thread;

/**
 * 对目标线程调用interrupt方法可以中断一个线程,目标线程通过检查isInterrupted标志获取自身是否已中断,
 *  如果目标线程处于等待状态,该线程会捕获到InterruptedException.
 *
 * 目标线程检测到isInterrupted为true或者捕获了InterruptedException都应该理科结束自身线程;
 *
 * 通过标志位判断需要正确使用volatile关键字;
 *
 * volatile关键字解决了共享变量在线程间的可见性问题.
 * volatile保证时效性而不是原子性:volatile 只保证变量改动之后立刻回写，之后的新线程读取到的肯定是更新后的值，
 *                              但之前已经获取过此变量本地副本的线程无法得知主内存中这个变量有了修改
 *
 * volatile只保证:
 *      1.读主内存到本地副本
 *      2.操作本地副本
 *      3.回写主内存
 *
 * @author XiongWei
 * @date 2021/1/13
 */
public class InterruptThread {

    public static void main(String[] args) throws InterruptedException {
        Thread t = new MyThread();
        t.start();
        Thread.sleep(1);
        t.interrupt();
        t.join();
        System.out.println("end");
    }

//    public static void main(String[] args) throws InterruptedException {
//        HelloThread t = new HelloThread();
//        t.start();
//        Thread.sleep(1);
//        t.running = false;
//    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        int n = 0;
        while (!isInterrupted()) {
            n ++;
            System.out.println(n + " hello!");
        }
    }
}

class HelloThread extends Thread {
    public volatile boolean running = true;

    @Override
    public void run() {
        int n = 0;
        while (running) {
            n ++;
            System.out.println(n + " hello!");
        }
        System.out.println("end");
    }
}
